package com.unibeta.cloudtest.mesher.util;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;


public class XLSUtils {

	/**
	 * load xls dataset from xls file.
	 * 
	 * @param url
	 * @return
	 * @throws Exception
	 */
	public static LinkedHashMap<String, List<LinkedHashMap<String, Object>>> load(String filePath) throws Exception {
		return loadXls(filePath);
	}

	/**
	 * Exports the dataset to xls file.
	 * 
	 * @param fileName target xls file path
	 * @param dataset  of LinkedHashMap<String, List<LinkedHashMap<String, Object>>>
	 * @throws Exception
	 */
	public static void save(LinkedHashMap<String, List<LinkedHashMap<String, Object>>> dataset, String fileName)
			throws Exception {

		Workbook workbook = new HSSFWorkbook(); // 创建工作簿对象
		for (String title : dataset.keySet()) {

			List<LinkedHashMap<String, Object>> dataList = dataset.get(title);
			try {

				Sheet sheet = workbook.createSheet(title); // 创建工作表
				CellStyle columnTopStyle = getColumnTopStyle(workbook);// 获取列头样式对象
				CellStyle style = getStyle(workbook); // 单元格样式对象

				// 定义所需列数
				int columnNum = dataList.get(0).size();
				Row rowRowName = sheet.createRow(0); // 在索引2的位置创建行(最顶端的行开始的第二行)

				// 将列头设置到sheet的单元格中
				int n = 0;
				for (String key : dataList.get(0).keySet()) {
					Cell cellRowName = rowRowName.createCell(n++); // 创建列头对应个数的单元格
					// cellRowName.setCellType(HSSFCell.CELL_TYPE_STRING); // 设置列头单元格的数据类型
					HSSFRichTextString text = new HSSFRichTextString(key);
					cellRowName.setCellValue(text); // 设置列头单元格的值
					cellRowName.setCellStyle(columnTopStyle); // 设置列头单元格样式
				}

				// 将查询出的数据设置到sheet对应的单元格中
				for (int i = 0; i < dataList.size(); i++) {

					Object[] obj = dataList.get(i).values().toArray();// 遍历每个对象
					Row row = sheet.createRow(i + 1);// 创建所需的行数

					for (int j = 0; j < obj.length; j++) {
						Cell cell = null; // 设置单元格的数据类型

						cell = row.createCell(j, CellType.STRING);
						if (!"".equals(obj[j]) && obj[j] != null) {
							cell.setCellValue(obj[j].toString()); // 设置单元格的值
						}

						cell.setCellStyle(style); // 设置单元格样式
					}
				}
				// // 让列宽随着导出的列长自动适应
				// for (int colNum = 0; colNum < columnNum; colNum++) {
				// int columnWidth = sheet.getColumnWidth(colNum) / 256;
				// for (int rowNum = 0; rowNum < sheet.getLastRowNum();
				// rowNum++) {
				// Row currentRow;
				// // 当前行未被使用过
				// if (sheet.getRow(rowNum) == null) {
				// currentRow = sheet.createRow(rowNum);
				// } else {
				// currentRow = sheet.getRow(rowNum);
				// }
				// if (currentRow.getCell(colNum) != null) {
				// Cell currentCell = currentRow.getCell(colNum);
				// if (currentCell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
				// int length = currentCell.getStringCellValue()
				// .getBytes().length;
				// if (columnWidth < length) {
				// columnWidth = length;
				// }
				// }
				// }
				// }
				// if (colNum == 0) {
				// sheet.setColumnWidth(colNum, (columnWidth - 2) * 256);
				// } else {
				// sheet.setColumnWidth(colNum, (columnWidth + 4) * 256);
				// }
				// }

			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		FileOutputStream xls = new FileOutputStream(fileName);
		workbook.write(xls);
		xls.close();
	}

	/*
	 * 列头单元格样式
	 */
	static CellStyle getColumnTopStyle(Workbook workbook) {
//
//		// 设置字体
//		Font font = workbook.createFont();
//		// 设置字体大小
//		font.setFontHeightInPoints((short) 11);
//		// 字体加粗
//		font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
//		// 设置字体名字
//		font.setFontName("Arial");
//		// 设置样式;
		CellStyle style = workbook.createCellStyle();
//		// 设置底边框;
//		style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
//		// 设置底边框颜色;
//		style.setBottomBorderColor(HSSFColor.BLACK.index);
//		// 设置左边框;
//		style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
//		// 设置左边框颜色;
//		style.setLeftBorderColor(HSSFColor.BLACK.index);
//		// 设置右边框;
//		style.setBorderRight(HSSFCellStyle.BORDER_THIN);
//		// 设置右边框颜色;
//		style.setRightBorderColor(HSSFColor.BLACK.index);
//		// 设置顶边框;
//		style.setBorderTop(HSSFCellStyle.BORDER_THIN);
//		// 设置顶边框颜色;
//		style.setTopBorderColor(HSSFColor.BLACK.index);
//		// 在样式用应用设置的字体;
//		style.setFont(font);
//		// 设置自动换行;
//		style.setWrapText(false);
//		// 设置水平对齐的样式为居中对齐;
//		style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
//		// 设置垂直对齐的样式为居中对齐;
//		style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
//
		return style;

	}

//
//	/*
//	 * 列数据信息单元格样式
//	 */
	static CellStyle getStyle(Workbook workbook) {
		// 设置字体
		Font font = workbook.createFont();
		// 设置字体大小
		// font.setFontHeightInPoints((short)10);
		// 字体加粗
		// font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		// 设置字体名字
		font.setFontName("Arial");
		// 设置样式;
		CellStyle style = workbook.createCellStyle();
		// 设置底边框;
//		style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
//		// 设置底边框颜色;
//		style.setBottomBorderColor(HSSFColor.BLACK.index);
//		// 设置左边框;
//		style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
//		// 设置左边框颜色;
//		style.setLeftBorderColor(HSSFColor.BLACK.index);
//		// 设置右边框;
//		style.setBorderRight(HSSFCellStyle.BORDER_THIN);
//		// 设置右边框颜色;
//		style.setRightBorderColor(HSSFColor.BLACK.index);
//		// 设置顶边框;
//		style.setBorderTop(HSSFCellStyle.BORDER_THIN);
//		// 设置顶边框颜色;
//		style.setTopBorderColor(HSSFColor.BLACK.index);
//		// 在样式用应用设置的字体;
//		style.setFont(font);
//		// 设置自动换行;
//		style.setWrapText(false);
//		// 设置水平对齐的样式为居中对齐;
//		style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
//		// 设置垂直对齐的样式为居中对齐;
//		style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

		return style;

	}

	private static LinkedHashMap<String, List<LinkedHashMap<String, Object>>> loadXls(String filePath)
			throws Exception {

		LinkedHashMap<String, List<LinkedHashMap<String, Object>>> xmlmap = new LinkedHashMap<String, List<LinkedHashMap<String, Object>>>();

		Workbook wb = getWorkbook(filePath);
		if (wb == null) {
			throw new Exception("invalid or unsupported file path is: '" + filePath + "'");
		}

		Iterator<Sheet> it = wb.sheetIterator();
		while (it.hasNext()) {

			ArrayList<String> columns = new ArrayList<String>();
			List<LinkedHashMap<String, Object>> list = new ArrayList<LinkedHashMap<String, Object>>();
			Sheet sheet = it.next();

			for (int i = 0; i <= sheet.getLastRowNum(); i++) {
				LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>();
				Row row = sheet.getRow(i);

				if (row != null) {
					for (int j = 0; j < sheet.getRow(0).getLastCellNum(); j++) {
						Object cellData = getCellFormatValue(row.getCell(j));
						if (i == 0) {
							columns.add(cellData.toString());
						} else {
							map.put(columns.get(j), cellData);
						}
					}

				} else {
					break;
				}
				if (i > 0) {
					list.add(map);
				}
			}

			xmlmap.put(sheet.getSheetName(), list);
		}

		wb.close();
		return xmlmap;
	}

	static Workbook getWorkbook(String filePath) {
		Workbook wb = null;

		if (filePath == null
				|| (!filePath.toLowerCase().endsWith(".xls") && !filePath.toLowerCase().endsWith(".xlsx"))) {
			return null;
		}

		String extString = filePath.substring(filePath.lastIndexOf("."));
		InputStream is = null;
		try {
			is = new FileInputStream(filePath);
			if (".xls".equalsIgnoreCase(extString)) {
				wb = new HSSFWorkbook(is);
			} else if (".xlsx".equalsIgnoreCase(extString)) {
				wb = new XSSFWorkbook(is);
			}

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(is != null) {
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
		return wb;
	}

	private static Object getCellFormatValue(Cell cell) {
		Object cellValue = null;
		
//		if(null ==cell) {
//			return null;
//		}
		
//		if(DateUtil.isCellDateFormatted(cell)) {
//			return cell.getDateCellValue();
//		}else if(cell.getCellType().equals(CellType.BOOLEAN)){
//			return cell.getBooleanCellValue();
//		}else{
//			cell.setCellType(CellType.STRING);
//			return cell.getRichStringCellValue().toString();
//		}
		
		if (cell != null) {
			switch (cell.getCellType()) {
			case NUMERIC: {
				if (DateUtil.isCellDateFormatted(cell)) {
					cellValue = cell.getDateCellValue();

				} else {
					//BigDecimal df = new BigDecimal((Double) cell.getNumericCellValue());
					//cellValue = cell.getStringCellValue();//df.toPlainString();
					
					DataFormatter format = new DataFormatter();
					cellValue = format.formatCellValue(cell);
					
				}
				break;
			}
			case FORMULA: {
				if (DateUtil.isCellDateFormatted(cell)) {
					cellValue = cell.getDateCellValue();

				} else {
					BigDecimal df = new BigDecimal((Double) cell.getNumericCellValue());
					cellValue = cell.getNumericCellValue();//df.toPlainString();
					
				}
				break;
			}
			case STRING: {
				cellValue = cell.getRichStringCellValue().getString();
				break;
			}
			case BOOLEAN: {
				cellValue = cell.getBooleanCellValue();
				break;
			}
			default: {
				cellValue = cell.getRichStringCellValue().toString();
			}
			}
		} else {
			cellValue = "";
		}

		return cellValue;
	}

}
